package uba.ing2.subite.demo;

import java.io.IOException;

import org.apache.pivot.collections.Map;
import org.apache.pivot.serialization.SerializationException;
import org.apache.pivot.wtk.Application;
import org.apache.pivot.wtk.DesktopApplicationContext;
import org.apache.pivot.wtk.Display;
import org.apache.pivot.wtkx.WTKXSerializer;

import uba.ing2.subite.domain.Account;
import uba.ing2.subite.domain.DisposableCard;
import uba.ing2.subite.services.SystemClock;
import uba.ing2.subite.services.authorizationrules.BalanceVerificationRule;
import uba.ing2.subite.services.authorizationrules.CompositePaymentAuthorizationRule;
import uba.ing2.subite.services.authorizationrules.PaymentAuthorizationRule;
import uba.ing2.subite.services.authorizationrules.PaymentCardVerificationRule;
import uba.ing2.subite.services.impl.AccountServiceImpl;
import uba.ing2.subite.services.impl.PaymentCardServiceImpl;
import uba.ing2.subite.services.impl.PaymentRegistrationServiceImpl;
import uba.ing2.subite.services.impl.PaymentServiceImpl;


/**
 * Aplicación de demostración para la prueba de concepto.
 */
public class SubiteDemoApplication implements Application {
    private SubiteDemoWindow window = null;
	private PaymentServiceImpl paymentService;
	private PaymentRegistrationServiceImpl paymentRegistrationService;
	private PaymentCardServiceImpl paymentCardService;
	private AccountServiceImpl accountService;

    public static void main(String[] args) {
    	DesktopApplicationContext.main(SubiteDemoApplication.class, args);
    }

	@Override
	public boolean shutdown(boolean arg0) throws Exception {
        if (window != null) {
            window.close();
        }

        return false;
	}

	@Override
	public void startup(Display display, Map<String, String> properties) throws Exception {
		createServices();
        createDemoWindow();
        window.open(display);
	}

	private void createServices() {
		accountService = new AccountServiceImpl(SystemClock.getInstance());
		paymentCardService = new PaymentCardServiceImpl(SystemClock.getInstance());
		PaymentAuthorizationRule authorizationRules = CompositePaymentAuthorizationRule
			.withAll(
					new BalanceVerificationRule(accountService),
					new PaymentCardVerificationRule(paymentCardService));
		
		paymentRegistrationService = new PaymentRegistrationServiceImpl();
		
		paymentService = new PaymentServiceImpl(SystemClock.getInstance(), 
				authorizationRules,
				accountService,
				paymentRegistrationService);
	}

	private void createDemoWindow() throws IOException, SerializationException {
		WTKXSerializer wtkxSerializer = new WTKXSerializer();
		window = (SubiteDemoWindow) wtkxSerializer.readObject(this, "subite_demo_window.wtkx");
		window.initializeWith(createDemoModel(), paymentService, paymentRegistrationService);
	}

	private SubiteDemoModel createDemoModel() {
		Account accountWithBalance = accountService.createAccount(100.0);

		return 	new SubiteDemoModelBuilder()
			.addTicketValue(1.10)
			.addTicketValue(1.25)
			.addTicketValue(1.75)
			.addTicketValue(1.90)
			.addTicketValue(2.00)
			.addCard(paymentCardService.newDisposableCardWith(20.0), "Descartable saldo inicial $20")
			.addCard(paymentCardService.newPrepaidCardFor(accountWithBalance), "Prepaga saldo inicial $100")
			.addCard(new DisposableCard("XXXX", 100.0), "Tarjeta no valida")
			.build();
	}

	@Override
	public void resume() throws Exception {}

	@Override
	public void suspend() throws Exception {}
}
